package com.centaline.androidsalesblog.fragments.map;

import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;

import com.android.volley.VolleyError;
import com.baidu.location.BDLocation;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.Marker;
import com.baidu.mapapi.model.LatLng;
import com.centaline.androidsalesblog.R;
import com.centaline.androidsalesblog.activities.newest.NewEstDetailActivity;
import com.centaline.androidsalesblog.api.newest.NewEstMapSearchApi;
import com.centaline.androidsalesblog.base.BaseMainMapFragment;
import com.centaline.androidsalesblog.constants.AppConstant;
import com.centaline.androidsalesblog.constants.CommonConstant;
import com.centaline.androidsalesblog.constants.ExtraConstant;
import com.centaline.androidsalesblog.iml.BaiduMarkerClick;
import com.centaline.androidsalesblog.iml.DropCompleteListener;
import com.centaline.androidsalesblog.model.businissobject.DropBo;
import com.centaline.androidsalesblog.model.businissobject.NewEstMainMapBo;
import com.centaline.androidsalesblog.model.databaseobject.NewEstDo;
import com.centaline.androidsalesblog.model.responseobject.NewEstListRo;
import com.centaline.androidsalesblog.overlay.local.NewEstRegionLevelOverlay;
import com.centaline.androidsalesblog.overlay.local.NewPropMapOverlay;
import com.centaline.androidsalesblog.rx.database.NewEstSearchDataFunc1;
import com.centaline.androidsalesblog.rx.database.RxDataBase;
import com.centaline.androidsalesblog.utils.DateUtil;
import com.centaline.androidsalesblog.utils.DropUtil;
import com.centaline.androidsalesblog.widgets.dropdown.DoubleDrop;
import com.centaline.androidsalesblog.widgets.dropdown.MoreDrop;
import com.centaline.androidsalesblog.widgets.dropdown.SalePriceDrop;
import com.centaline.androidsalesblog.widgets.dropdown.SingleDrop;
import com.centanet.framework.interfaces.IResponseListener;
import com.trello.rxlifecycle.FragmentEvent;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.functions.Func2;
import rx.functions.Func3;
import rx.schedulers.Schedulers;

/**
 * 新盘地图找房
 * Created by guilin on 16/4/13.
 */
public class NewEstMainMapFragment extends BaseMainMapFragment {

    private DoubleDrop doubleDrop;
    private SalePriceDrop salePriceDrop;
    private SingleDrop singleDrop;
    private MoreDrop moreDrop;

    private NewEstRegionLevelOverlay newEstRegionLevelOverlay;
    private NewPropMapOverlay newPropMapOverlay;

    private NewEstMapSearchApi newEstMapSearchApi;
    private ArrayList<NewEstDo> newEstDoArrayList = new ArrayList<>();//楼盘
    private ArrayList<NewEstMainMapBo> newEstMainMapBos = new ArrayList<>();//区域板块显示
    private ArrayList<NewEstMainMapBo> regionList = new ArrayList<>();//区域
    private ArrayList<NewEstMainMapBo> gscopList = new ArrayList<>();//板块

    @Override
    protected DropCompleteListener getDropCompleteListener() {
        dropCompleteListener = new DropCompleteListener() {
            @Override
            public void complete(int position, boolean fromMore, int type, DropBo... dropBos) {
                final int size = dropBos == null ? 0 : dropBos.length;
                if (fromMore) {
                    newEstMapSearchApi.resetOther();
                    if (size == 0) {
                        resetTab(3);
                        requestList(false);
                    } else {
                        setTab(3, "更多");
                        StringBuilder tags = new StringBuilder();
                        for (DropBo dropBo : dropBos) {
                            final int innerType = dropBo.getType();
                            switch (innerType) {
                                case 40://户型
                                    if (dropBo.getValue() != null &&
                                            dropBo.getValue().contains(",")) {
                                        String[] rooms = dropBo.getValue().split(",");
                                        if (rooms[0].equals(rooms[1])) {
                                            newEstMapSearchApi.setRoomCnt(rooms[0]);
                                            newEstMapSearchApi.setGtRoomCnt("0");
                                        } else {
                                            newEstMapSearchApi.setRoomCnt(rooms[0]);
                                            newEstMapSearchApi.setGtRoomCnt("1");
                                        }
                                    }
                                    break;
                                case 130://开盘时间
                                    if (dropBo.getValue() != null &&
                                            dropBo.getValue().contains(",")) {
                                        String[] op = dropBo.getValue().split(",");
                                        Calendar calendar = Calendar.getInstance();
                                        calendar.setTime(new Date());
                                        int begin = Integer.parseInt(op[0]);
                                        int end = Integer.parseInt(op[1]);
                                        if (begin != 0) {
                                            calendar.add(Calendar.MONTH, begin);
                                        }
                                        newEstMapSearchApi.setOpDateBegin(DateUtil.format(begin == 0 ?
                                                        System.currentTimeMillis() : calendar.getTimeInMillis(),
                                                DateUtil.FORMAT2));
                                        if (end != 0) {
                                            calendar.add(Calendar.MONTH, end);
                                        }
                                        newEstMapSearchApi.setOpDateEnd(DateUtil.format(end == 0 ?
                                                        System.currentTimeMillis() : calendar.getTimeInMillis(),
                                                DateUtil.FORMAT2));
                                    }
                                    break;
                                case 80://特色
                                    tags.append(dropBo.getValue()).append(",");
                                    break;
                                default:
                                    break;
                            }
                        }
                        if (tags.toString().contains(",")) {
                            tags.deleteCharAt(tags.length() - 1);
                        }
                        newEstMapSearchApi.setTags(tags.toString());
                        requestList(false);
                    }
                } else {
                    switch (type) {
                        case 10://区域
                            if (size == 1) {
                                if (DropUtil.compareValue(dropBos[0])) {
                                    resetTab(position);
                                    baiduMap.animateMapStatus(MapStatusUpdateFactory.zoomTo(12f));
                                } else {
                                    setTab(position, dropBos[0].getText());
                                    for (NewEstMainMapBo newEstMainMapBo : regionList) {
                                        if (dropBos[0].getValue().equalsIgnoreCase(newEstMainMapBo.getGscopId())) {
                                            baiduMap.animateMapStatus(MapStatusUpdateFactory.newLatLngZoom(
                                                    newEstMainMapBo.getLatLng(), 14f));
                                            break;
                                        }
                                    }
                                }
                            } else if (size == 2) {
                                if (DropUtil.compareValue(dropBos[1])) {
                                    setTab(position, dropBos[0].getText());
                                    for (NewEstMainMapBo newEstMainMapBo : regionList) {
                                        if (dropBos[0].getValue().equalsIgnoreCase(newEstMainMapBo.getGscopId())) {
                                            baiduMap.animateMapStatus(MapStatusUpdateFactory.newLatLngZoom(
                                                    newEstMainMapBo.getLatLng(), 14f));
                                            break;
                                        }
                                    }
                                } else {
                                    setTab(position, dropBos[1].getText());
                                    for (NewEstMainMapBo newEstMainMapBo : gscopList) {
                                        if (dropBos[1].getValue().equalsIgnoreCase(newEstMainMapBo.getGscopId())) {
                                            baiduMap.animateMapStatus(MapStatusUpdateFactory.newLatLngZoom(
                                                    newEstMainMapBo.getLatLng(), 17f));
                                            break;
                                        }
                                    }
                                }
                            }
                            break;
                        case 11://附近
                            if (size == 2) {
                                startLocation();
                                if ("1000".equals(dropBos[1].getValue())) {
                                    distance = 1000;
                                } else if ("1500".equals(dropBos[1].getValue())) {
                                    distance = 1500;
                                } else {
                                    distance = 2000;
                                }
                                setTab(position, dropBos[1].getText());
                            }
                            break;
                        case 30://均价
                            if (size == 1) {
                                final String value = dropBos[0].getValue();
                                if (TextUtils.isEmpty(value)) {
                                    newEstMapSearchApi.setMinAveragePrice("");
                                    newEstMapSearchApi.setMaxAveragePrice("");
                                    resetTab(position);
                                    requestList(false);
                                } else if (value.contains(",")) {
                                    String[] values = value.split(",");
                                    newEstMapSearchApi.setMinAveragePrice(values[0]);
                                    newEstMapSearchApi.setMaxAveragePrice(values[1]);
                                    setTab(position, dropBos[0].getText());
                                    requestList(false);
                                }
                            } else if (size == 2) {
                                newEstMapSearchApi.setMinAveragePrice(dropBos[0].getValue());
                                newEstMapSearchApi.setMaxAveragePrice(dropBos[1].getValue());
                                setTab(position, DropUtil.customPrice(dropBos[0], dropBos[1]));
                                requestList(false);
                            }
                            break;
                        case 110://物业类型
                            newEstMapSearchApi.setEstType("");
                            if (size == 1) {
                                if (TextUtils.isEmpty(dropBos[0].getValue())||
                                        "不限".equalsIgnoreCase(dropBos[0].getValue())||
                                        "全部".equalsIgnoreCase(dropBos[0].getValue())) {
                                    resetTab(position);
                                } else {
                                    newEstMapSearchApi.setEstType(dropBos[0].getValue());
                                    setTab(position, dropBos[0].getText());
                                }
                            }
                            requestList(false);
                            break;
                        default:
                            break;
                    }
                }
            }
        };
        return dropCompleteListener;
    }

    @Override
    protected void initDrop() {
        dropDownView.initTabs(R.array.newEst);
        doubleDrop = new DoubleDrop(dropDownView, getActivity());
        salePriceDrop = new SalePriceDrop(dropDownView, getActivity());
        singleDrop = new SingleDrop(dropDownView, getActivity());
        moreDrop = new MoreDrop(dropDownView, getActivity());
        dropDownView.addDrops(doubleDrop, salePriceDrop, singleDrop, moreDrop);

        Observable
                .combineLatest(RxDataBase
                                .getNewEstRegion()
                                .subscribeOn(Schedulers.io()),
                        RxDataBase.nearby(),
                        new Func2<ArrayList<DropBo>, DropBo, ArrayList<DropBo>>() {
                            @Override
                            public ArrayList<DropBo> call(ArrayList<DropBo> dropBos, DropBo dropBo) {
                                ArrayList<DropBo> temp = new ArrayList<>();
                                DropBo dropBo2 = new DropBo(10);
                                dropBo2.setText(CommonConstant.DROP_TEXT_NO_LIMITED);
                                dropBo2.setValue(CommonConstant.DROP_VALUE_NULL);
                                temp.add(dropBo2);
                                temp.addAll(dropBos);
                                if (AppConstant.NearbyEnable) {
                                    temp.add(dropBo);
                                }
                                return temp;
                            }
                        })
                .compose(this.<ArrayList<DropBo>>bindUntilEvent(FragmentEvent.DESTROY))
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<ArrayList<DropBo>>() {
                    @Override
                    public void call(ArrayList<DropBo> dropBos) {
                        doubleDrop.init(dropBos);
                    }
                });
        RxDataBase
                .getSearchData("NewHousePriceN")
                .map(new NewEstSearchDataFunc1(30))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .compose(this.<ArrayList<DropBo>>bindUntilEvent(FragmentEvent.DESTROY))
                .subscribe(new Action1<ArrayList<DropBo>>() {
                    @Override
                    public void call(ArrayList<DropBo> dropBos) {
                        salePriceDrop.init(dropBos);
                    }
                });
        RxDataBase
                .getSearchData("NewEstType")
                .map(new NewEstSearchDataFunc1(110))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .compose(this.<ArrayList<DropBo>>bindUntilEvent(FragmentEvent.DESTROY))
                .subscribe(new Action1<ArrayList<DropBo>>() {
                    @Override
                    public void call(ArrayList<DropBo> dropBos) {
                        singleDrop.init(dropBos);
                    }
                });

        Observable
                .combineLatest(
                        RxDataBase.getSearchData("Room").map(new NewEstSearchDataFunc1(40)),
                        RxDataBase.getSearchData("NewPropOpDate").map(new NewEstSearchDataFunc1(130)),
                        RxDataBase.getSearchData("NewPropFeatures").map(new NewEstSearchDataFunc1(80)),
                        new Func3<ArrayList<DropBo>, ArrayList<DropBo>, ArrayList<DropBo>, ArrayList<DropBo>>() {
                            @Override
                            public ArrayList<DropBo> call(ArrayList<DropBo> dropBos, ArrayList<DropBo> dropBos2, ArrayList<DropBo> dropBos3) {
                                final ArrayList<DropBo> list = new ArrayList<>();
                                DropBo dropBo;
                                if (dropBos2.size() > 0) {
                                    dropBo = new DropBo(40);
                                    dropBo.setText("户型");
                                    dropBo.setValue(CommonConstant.DROP_VALUE_NULL);
                                    dropBo.setChildrenList(dropBos);
                                    list.add(dropBo);
                                }
                                if (dropBos3.size() > 0) {
                                    dropBo = new DropBo(130);
                                    dropBo.setText("开盘时间");
                                    dropBo.setValue(CommonConstant.DROP_VALUE_NULL);
                                    dropBo.setChildrenList(dropBos2);
                                    list.add(dropBo);
                                }
                                if (dropBos2.size() > 0) {
                                    dropBo = new DropBo(80);
                                    dropBo.setText("特色");
                                    dropBo.setSelected(true);
                                    dropBo.setValue(CommonConstant.DROP_VALUE_NULL);
                                    dropBo.setChildrenList(dropBos3);
                                    list.add(dropBo);
                                }
                                return list;
                            }
                        })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .compose(this.<ArrayList<DropBo>>bindUntilEvent(FragmentEvent.DESTROY))
                .subscribe(new Action1<ArrayList<DropBo>>() {
                    @Override
                    public void call(ArrayList<DropBo> dropBos) {
                        moreDrop.init(dropBos);
                    }
                });
    }

    @Override
    protected void initOther() {
        newEstMapSearchApi = new NewEstMapSearchApi(NewEstMainMapFragment.class, NewEstListRo.class,
                new IResponseListener<NewEstListRo>() {
                    @Override
                    public void onResponse(NewEstListRo newEstListRo) {
                        cancelLoadingDialog();
                        newEstDoArrayList.clear();
                        regionList.clear();
                        gscopList.clear();
                        if (newEstListRo.getNewEstDoArrayList() != null) {
                            newEstDoArrayList.addAll(newEstListRo.getNewEstDoArrayList());
                        }
                        ArrayList<String> regionKey = new ArrayList<>();
                        ArrayList<String> gscopKey = new ArrayList<>();
                        NewEstMainMapBo newEstMainMapBo;
                        for (NewEstDo newEstDo : newEstDoArrayList) {
                            //区域
                            String districtId = String.valueOf(newEstDo.getDistrictId());
                            if (regionKey.contains(districtId)) {
                                regionList.get(regionKey.indexOf(districtId)).add();
                                if (newEstDo.getNewEstDistrictBo() != null) {
                                    regionList.get(regionKey.indexOf(districtId)).setName(
                                            newEstDo.getNewEstDistrictBo().getGScopeCnName());
                                    if (newEstDo.getNewEstDistrictBo().getLat() != 0 &&
                                            newEstDo.getNewEstDistrictBo().getLng() != 0) {
                                        regionList.get(regionKey.indexOf(districtId))
                                                .setLatLng(new LatLng(
                                                        newEstDo.getNewEstDistrictBo().getLat(),
                                                        newEstDo.getNewEstDistrictBo().getLng()));
                                    }
                                }
                            } else {
                                regionKey.add(districtId);
                                newEstMainMapBo = new NewEstMainMapBo(1, districtId);
                                newEstMainMapBo.add();
                                if (newEstDo.getNewEstDistrictBo() != null) {
                                    newEstMainMapBo.setName(newEstDo.getNewEstDistrictBo().getGScopeCnName());
                                    if (newEstDo.getNewEstDistrictBo().getLat() != 0 &&
                                            newEstDo.getNewEstDistrictBo().getLng() != 0) {
                                        newEstMainMapBo.setLatLng(new LatLng(
                                                newEstDo.getNewEstDistrictBo().getLat(),
                                                newEstDo.getNewEstDistrictBo().getLng()));
                                    }
                                }
                                regionList.add(newEstMainMapBo);
                            }
                            //板块
                            String gscopId = String.valueOf(newEstDo.getGScopeId());
                            if (gscopKey.contains(gscopId)) {
                                gscopList.get(gscopKey.indexOf(gscopId)).add();
                                if (newEstDo.getNewEstGScopeBo() != null) {
                                    gscopList.get(gscopKey.indexOf(gscopId)).setName(
                                            newEstDo.getNewEstGScopeBo().getGScopeCnName());
                                    if (newEstDo.getNewEstGScopeBo().getLat() != 0 &&
                                            newEstDo.getNewEstGScopeBo().getLng() != 0) {
                                        gscopList.get(gscopKey.indexOf(gscopId))
                                                .setLatLng(new LatLng(
                                                        newEstDo.getNewEstGScopeBo().getLat(),
                                                        newEstDo.getNewEstGScopeBo().getLng()));
                                    }
                                }
                            } else {
                                gscopKey.add(gscopId);
                                newEstMainMapBo = new NewEstMainMapBo(2, gscopId);
                                newEstMainMapBo.add();
                                if (newEstDo.getNewEstGScopeBo() != null) {
                                    newEstMainMapBo.setName(newEstDo.getNewEstGScopeBo().getGScopeCnName());
                                    if (newEstDo.getNewEstGScopeBo().getLat() != 0 &&
                                            newEstDo.getNewEstGScopeBo().getLng() != 0) {
                                        newEstMainMapBo.setLatLng(new LatLng(
                                                newEstDo.getNewEstGScopeBo().getLat(),
                                                newEstDo.getNewEstGScopeBo().getLng()));
                                    }
                                }
                                gscopList.add(newEstMainMapBo);
                            }
                        }
                        updateMap(true);
                    }

                    @Override
                    public void onErrorResponse(VolleyError error) {
                        cancelLoadingDialog();
                        toast(getString(R.string.network_unable));
                    }
                });
        newEstMapSearchApi.setLength(1000);

        newEstRegionLevelOverlay = new NewEstRegionLevelOverlay(getActivity(), baiduMap, newEstMainMapBos,
                new BaiduMarkerClick() {
                    @Override
                    public boolean onMarkerClick(Marker marker) {
                        if (marker != null) {
                            Bundle bundle = marker.getExtraInfo();
                            if (bundle != null) {
                                NewEstMainMapBo newEstMainMapBo = bundle.getParcelable(ExtraConstant.MAP_EXTRA_INFO);
                                if (newEstMainMapBo != null) {
                                    switch (newEstMainMapBo.getLevel()) {
                                        case 1://区域点击
                                            baiduMap.animateMapStatus(MapStatusUpdateFactory.newLatLngZoom(
                                                    newEstMainMapBo.getLatLng(), 14f));
                                            break;
                                        case 2://板块点击
                                            baiduMap.animateMapStatus(MapStatusUpdateFactory.newLatLngZoom(
                                                    newEstMainMapBo.getLatLng(), 15f));
                                            break;
                                        default:
                                            break;
                                    }
                                    return true;
                                }
                            }
                        }
                        return false;
                    }
                });
        baiduMap.setOnMarkerClickListener(newEstRegionLevelOverlay);

        newPropMapOverlay = new NewPropMapOverlay(getActivity(), baiduMap, newEstDoArrayList, new BaiduMarkerClick() {
            @Override
            public boolean onMarkerClick(Marker marker) {
                if (marker != null) {
                    Bundle bundle = marker.getExtraInfo();
                    if (bundle != null &&
                            bundle.getParcelable(ExtraConstant.MAP_EXTRA_INFO) instanceof NewEstDo) {
                        NewEstDo newEstDo = bundle.getParcelable(ExtraConstant.MAP_EXTRA_INFO);
                        if (newEstDo != null) {
                            startActivity(new Intent(getContext(), NewEstDetailActivity.class)
                                    .putExtra(ExtraConstant.NewEstId, newEstDo.getEstExtId()));
                            return true;
                        }
                    }
                }
                return false;
            }
        });
        baiduMap.setOnMarkerClickListener(newPropMapOverlay);
    }

    @Override
    protected void requestList(boolean needLocation) {
        if (needLocation) {
            startLocation();
        } else {
            showLoadingDialog();
            newEstMapSearchApi.startRequest();
        }
    }

    /**
     * 更新地图
     */
    private void updateMap(boolean reset) {
        if (endZoom < 14f) {//区域
            newPropMapOverlay.removeFromMap();
            if (reset || startZoom >= 14f) {
                newEstMainMapBos.clear();
                newEstRegionLevelOverlay.removeFromMap();
                newEstMainMapBos.addAll(regionList);
                newEstRegionLevelOverlay.mapStatusChange();
            }
            if (endZoom < 12f) {
                baiduMap.animateMapStatus(MapStatusUpdateFactory.newLatLngZoom(cityCenter, 12f));
            }
        } else if (endZoom < 15f) {//板块
            newPropMapOverlay.removeFromMap();
            if (reset || startZoom < 14f || startZoom >= 15f) {
                newEstRegionLevelOverlay.removeFromMap();
                newEstMainMapBos.clear();
                newEstRegionLevelOverlay.removeFromMap();
                newEstMainMapBos.addAll(gscopList);
                newEstRegionLevelOverlay.mapStatusChange();
            }
        } else {
            newEstRegionLevelOverlay.removeFromMap();
            if (reset) {
                newPropMapOverlay.removeFromMap();
            }
            if (reset || startZoom < 15f) {
                newPropMapOverlay.mapStatusChange();
            }
        }
    }

    @Override
    public void onMapStatusChangeFinish(MapStatus mapStatus) {
        super.onMapStatusChangeFinish(mapStatus);
        updateMap(false);
    }

    @Override
    protected void locationInfo(BDLocation bdLocation) {
        switch (bdLocation.getLocType()) {
            case 61:
            case 161:
                float zoom = distance == 1000 ? 18f : distance == 1500 ? 17.8f : 17.5f;
                baiduMap.animateMapStatus(MapStatusUpdateFactory.newLatLngZoom(
                        new LatLng(bdLocation.getLatitude(), bdLocation.getLongitude()), zoom));
                break;
            default:
                break;
        }
    }
}
